// the world of scarlet.
// the world of BRUTE FORCE!!
#include<bits/stdc++.h>
#define ll long long
#define F(i, a, b) for(int (i)=(a);(i)<=(b);++(i))
#define dF(i, a, b) for(int (i)=(a);(i)>=(b);--(i))
#define mkp make_pair
#define endl '\n'
#define ENDL putchar('\n')
#define forGraph(x) for(int i = head[x]; i; i = G[i].nxt)
#define pii pair<int, int>
#define pb push_back
#define fi first
#define se second
using namespace std;

template<typename T>void read(T &x) {
    x = 0;
    char ch = getchar(); bool f = 0;
    while(!isdigit(ch)) {f |= (ch == '-'); ch = getchar();}
    while(isdigit(ch)) {x = x * 10 + (ch - '0'); ch = getchar();}
    x = (f ? -x : x);
}

template<typename T>void write(T x) {
    if(x < 0) {putchar('-'); x = -x;}
    char _buf[70]; int p = 0;
    do{_buf[++p] = x % 10 + '0'; x /= 10;} while(x);
    do{putchar(_buf[p--]);} while(p);
}

const int N = 5e5 + 5, M = 1e6 + 5;

struct Graph{
    int to, w, nxt;
}G[M << 1];
int head[N], g_cnt;
void addEdge(int u, int v, int w = 1) {
    G[++g_cnt] = (Graph){v, w, head[u]}; head[u] = g_cnt;
}

ll n, m, p, q, r, T, L, V;
ll a[N];

void solve();

int main() {
    freopen("detect.in", "r", stdin);
    freopen("detect.out", "w", stdout);
    read(T);
    while(T--) {
        solve();
    }
}

struct car {
    ll x, v, a;
}c[N];
ll h[N], cnt, ans;
vector<pii> vec;

int judge(int p, long long *t, int o) {
    ll x = c[p].x, v = c[p].v, a = c[p].a;
    if(x > t[o]) return 0;
    if(a == 0) {
        int pos = lower_bound(t + 1, t + o + 1, x) - t;
        int num = o - pos + 1;
        if(num > 0 && v > V) {
            return 1;
        }
        else return 0;
    }
    if(a > 0) {
        int pos = lower_bound(t + 1, t + o + 1, x) - t;
        // v^2 - v0^2 = 2ax
        // v^2 = 2ax + v0^2
        F(i, pos, o) {
            ll v_sq = 2 * a * (t[i] - x) + v * v;
            if(v_sq > V * V) {
                return 1;
            }
        }
        return 0;
    }
    if(a < 0) {
        int pos = lower_bound(t + 1, t + o + 1, x) - t;
        // v^2 - v0^2 = 2ax
        // v^2 = 2ax + v0^2
        F(i, pos, o) {
            ll v_sq = 2 * a * (t[i] - x) + v * v;
            if(v_sq <= 0) return 0;
            if(v_sq > V * V) {
                return 1;
            }
        }
    }
}

bool cmp1(pii A, pii B) {
    if(A.fi == B.fi) return A.se < B.se;
    return A.fi < B.fi;
}

void chkmax(int &x, int y) {
    x = x < y ? y : x;
}

bool b[N];
ll h_c[N], ans_c = 0;

void Check() {
    ll cnt = 0, cnt_c = 0, rans = 0;
    F(i, 1, m) {
        if(b[i] == 1) {
            h_c[++cnt] = h[i];
        }
        else cnt_c++;
    }
    if(cnt_c == m) return;
    F(i, 1, n) {
        rans += judge(i, h_c, cnt);
    }
    if(rans == ans) {
        ans_c = max(ans_c, cnt_c);
    }
}

void dfs(int cur) {
    if(cur == m + 1) {
        Check();
        return;
    }
    b[cur] = 0;
    dfs(cur + 1);
    b[cur] = 1;
    dfs(cur + 1);
}

void solve() {
    ans_c = 0;
    map<int, int> mp;
    vec.clear();
    ans = 0;
    bool flag = 1;
    read(n); read(m); read(L); read(V);
    F(i, 1, n) {
        read(c[i].x); read(c[i].v); read(c[i].a);
        if(c[i].a < 0) flag = 0;
    }
    F(i, 1, m) read(h[i]);
    F(i, 1, n) {
        ans += judge(i, h, m);
    }
    write(ans); putchar(' ');
    if(flag) {
        write(m - 1); putchar('\n');
    }
    else if(m <= 20) {
        dfs(1);
        write(ans_c);
        putchar('\n');
    }
}
// Why Prob 2 So Hard?
// Sleepy......
// Having no idea at all...
// 16:09 maybe know something...
// proved wrong!!?!!!?!!
// loser.
// Nice!!! Think of a 40% Solution!!! [at 17: 47]
